﻿using System;
using System.Collections.Generic;

namespace QFramework
{
    public class SlotGroup
    {
        public string Key = String.Empty;

        private List<Slot> mSlots = new List<Slot>();

        private Func<IItem, bool> mCondition = _ => true;
        public IReadOnlyList<Slot> Slots => mSlots;
        
        public bool CheckCondition(IItem item)
        {
            return mCondition(item);
        }
        
        /// <summary>
        /// 添加进列表
        /// </summary>
        public SlotGroup CreateSlot(IItem item, int count)
        {
            mSlots.Add(new Slot(item, count, this));
            return this;
        }

        public SlotGroup CreateSlotsByCount(int count)
        {
            for (int i = 0; i < count; i++)
            {
                CreateSlot(null, 0);
            }
            return this;
        }
        
        /// <summary>
        /// 根据key找格子
        /// </summary>
        public Slot FindSlotByKey(string key)
        {
            return mSlots.Find(s => s.Item is not null && s.Item.GetKey == key && s.Count != 0);
        }

        /// <summary>
        /// 找到空格子
        /// </summary>
        public Slot FindEmptySlot()
        {
            return mSlots.Find(s => s.Count == 0);
        }
        
        /// <summary>
        /// 找到可添加物品的格子
        /// </summary>
        /// <returns></returns>
        public Slot FindAddableSlot(string key)
        {
            var item = ItemKit.ItemByKey[key];
            
            if (!item.IsStackable) // 不可堆叠
            {
                var slot = FindEmptySlot();
                if (slot is not null)
                {
                    slot.Item = item;
                }

                return slot;
            }
            else if(item.IsStackable && !item.GetHasMaxStackableCount) // 可堆叠，并且没有最大堆叠数量
            {
                var slot = FindSlotByKey(key);
                
                if (slot is null)
                {
                    slot = FindEmptySlot();
                    if (slot is not null)
                    {
                        slot.Item = ItemKit.ItemByKey[key];
                    }
                }
                return slot;
            }
            else
            {
                return FindAddableHasMaxStackableCountSlot(key);
            }
        }
        
        public Slot FindAddableHasMaxStackableCountSlot(string itemKey)
        {
            foreach (var mSlot in mSlots)
            {
                if (mSlot.Count != 0 && mSlot.Item.GetKey == itemKey && mSlot.Item.GetMaxStackableCount > mSlot.Count)
                {
                    return mSlot;
                }
            }
            var emptySlot =  FindEmptySlot();
            if (emptySlot is not null)
            {
                emptySlot.Item = ItemKit.ItemByKey[itemKey];
            }

            return emptySlot;
        }

        public struct ItemOperateResult
        {
            public bool Succeed;
            public int RemainCount;
            public MessageTypes MessageType;
        }
        
        public enum MessageTypes
        {
            Full,
            
        }
        
        /// <summary>
        /// 添加物品
        /// </summary>
        public ItemOperateResult AddItem(string itemKey, int addCount = 1)
        {
            var item = ItemKit.ItemByKey[itemKey];

            // 可堆叠 并且 有最大堆叠数
            if (item.IsStackable && item.GetHasMaxStackableCount)
            {
                do
                {
                    var slot = FindAddableHasMaxStackableCountSlot(itemKey);
                    if (slot is not null)
                    {
                        int canAddCount = slot.Item.GetMaxStackableCount - slot.Count;
                        if (addCount <= canAddCount)
                        {
                            slot.Count += addCount;
                            slot.Changed.Trigger();
                            addCount = 0;
                        }
                        else
                        {
                            slot.Count += canAddCount;
                            slot.Changed.Trigger();
                            addCount -= canAddCount;
                        }
                    }
                    else
                    {
                        return new ItemOperateResult() { Succeed = false, RemainCount = addCount };
                    }
                } while (addCount > 0);
                return new ItemOperateResult() { Succeed = true, RemainCount = 0 };
            }
            else
            {
                var slot = FindAddableSlot(itemKey);
                if (slot is null)
                {
                    return new ItemOperateResult(){Succeed = false, RemainCount = 0};
                }
                slot.Count += addCount;
                slot.Changed.Trigger();
                return new ItemOperateResult(){Succeed = true, RemainCount = 0};
            }
        }

        /// <summary>
        /// 删除物品
        /// </summary>
        public bool SubItem(string itemKey, int subCount = 1)
        {
            var slot = FindSlotByKey(itemKey);
            if (slot is not null && slot.Count >= subCount)
            {
                slot.Count -= subCount;
                slot.Changed.Trigger();
                return true;
            }
            return false;
        }

        public SlotGroup Condition(Func<IItem, bool> condition)
        {
            mCondition = condition;
            return this;
        }
    }
}